package com.kedacom.demo.redis;

import java.util.HashMap;
import java.util.Map;

import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import redis.clients.jedis.JedisPoolConfig;

/**
 * 动态切换ConnectionFactory的RedisTemplate
 * @author luocanfeng
 * @date 2017年5月3日
 */
public class DynamicRedisTemplate<K, V> extends RedisTemplate<K, V> {

	private static String DEFAULT_LOOKUP_KEY = "default";

	private JedisPoolConfig poolConfig;
	private RedisConnectionFactory defaultConnectionFactory;
	private Map<String, JedisConnectionFactory> targetRedisConnectionFactories;

	@Override
	public void afterPropertiesSet() {
		super.afterPropertiesSet();

		if (CollectionUtils.isEmpty(this.targetRedisConnectionFactories)) {
			this.targetRedisConnectionFactories = new HashMap<String, JedisConnectionFactory>();
		}

		// if (this.defaultConnectionFactory == null
		// &&
		// this.targetRedisConnectionFactories.containsKey(DEFAULT_LOOKUP_KEY))
		// {
		// this.defaultConnectionFactory =
		// this.targetRedisConnectionFactories.get(DEFAULT_LOOKUP_KEY);
		// }

		if (poolConfig == null) {
			throw new IllegalArgumentException("Property 'poolConfig' is required");
		}
		if (defaultConnectionFactory == null) {
			throw new IllegalArgumentException("Property 'defaultConnectionFactory' is required");
		}
		// if (CollectionUtils.isEmpty(this.targetRedisConnectionFactories)) {
		// throw new IllegalArgumentException("Property
		// 'targetRedisConnectionFactories' is required");
		// }
	}

	@Override
	public void setConnectionFactory(RedisConnectionFactory connectionFactory) {
		this.setDefaultConnectionFactory(connectionFactory);
	}

	public void setPoolConfig(JedisPoolConfig poolConfig) {
		this.poolConfig = poolConfig;
	}

	public void setDefaultConnectionFactory(RedisConnectionFactory defaultConnectionFactory) {
		this.defaultConnectionFactory = defaultConnectionFactory;
	}

	public void setTargetRedisConnectionFactories(Map<String, JedisConnectionFactory> targetRedisConnectionFactories) {
		this.targetRedisConnectionFactories = targetRedisConnectionFactories;
	}

	@Override
	public RedisConnectionFactory getConnectionFactory() {
		return determineTargetConnection();
	}

	protected RedisConnectionFactory determineTargetConnection() {
		String lookupKey = determineCurrentLookupKey();
		if (DEFAULT_LOOKUP_KEY.equals(lookupKey)) {
			return this.defaultConnectionFactory;
		}
		RedisConnectionFactory connectionFactory = this.targetRedisConnectionFactories.get(lookupKey);
		if (connectionFactory == null) {
			throw new IllegalStateException(
					"Cannot determine target RedisConnectionFactory for lookup key [" + lookupKey + "]");
		}
		return connectionFactory;
	}

	protected String determineCurrentLookupKey() { // 在线程AOP中切换LookupKey
		return RedisConnectionFactorySwitcher.getLookupKey();
	}

	/**
	 * 接管平台域
	 */
	public void takeOver(String platformMoid, String redisHost, int redisPort, String redisPassword) {
		// TODO: 从配置文件加载redisPassword、redisHost？
		JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
		jedisConnectionFactory.setHostName(redisHost);
		jedisConnectionFactory.setPort(redisPort);
		jedisConnectionFactory.setPassword(redisPassword);
		jedisConnectionFactory.setUsePool(true);
		jedisConnectionFactory.setPoolConfig(this.poolConfig);
		jedisConnectionFactory.afterPropertiesSet();

		this.targetRedisConnectionFactories.put(platformMoid, jedisConnectionFactory);
	}

	/**
	 * 解除平台域的接管
	 */
	public void release(String platformMoid) {
		JedisConnectionFactory jedisConnectionFactory = this.targetRedisConnectionFactories.get(platformMoid);
		if (jedisConnectionFactory != null) {
			jedisConnectionFactory.destroy();
		}
		this.targetRedisConnectionFactories.remove(platformMoid);
	}

}
